package com.lengyue.imakiba.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.*; 
import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESKeySpec; 

public class FileTools {
	
	private static final String KEY = "imakibaKey";
	private static final String FILE_HEAD = "imakibaEncryptFileHead";
	private static final int ENBUFFERLEN = 512;//数据缓冲区的长度
	private static final int DEBUFFERLEN = 520;//解密时数据缓冲区的长度
	private final static String DES = "DES"; 
	

	/** 
	* 加密 
	* @param src 数据源 
	* @param key 密钥，长度必须是8的倍数 
	* @return 返回加密后的数据 
	* @throws Exception 
	*/ 
	public static byte[] encrypt(byte[] src, byte[] key)throws Exception { 
//	DES算法要求有一个可信任的随机数源 
	SecureRandom sr = new SecureRandom(); 
//	 从原始密匙数据创建DESKeySpec对象 
	DESKeySpec dks = new DESKeySpec(key); 
//	 创建一个密匙工厂，然后用它把DESKeySpec转换成 
//	 一个SecretKey对象 
	SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); 
	SecretKey securekey = keyFactory.generateSecret(dks); 
//	 Cipher对象实际完成加密操作 
	Cipher cipher = Cipher.getInstance(DES); 
//	 用密匙初始化Cipher对象 
	cipher.init(Cipher.ENCRYPT_MODE, securekey, sr); 
//	 现在，获取数据并加密 
//	 正式执行加密操作 
	return cipher.doFinal(src); 
	} 

	/** 
	* 解密 
	* @param src 数据源 
	* @param key 密钥，长度必须是8的倍数 
	* @return 返回解密后的原始数据 
	* @throws Exception 
	*/ 
	public static byte[] decrypt(byte[] src, byte[] key)throws Exception { 
//	 DES算法要求有一个可信任的随机数源 
	SecureRandom sr = new SecureRandom(); 
//	 从原始密匙数据创建一个DESKeySpec对象 
	DESKeySpec dks = new DESKeySpec(key); 
//	 创建一个密匙工厂，然后用它把DESKeySpec对象转换成 
//	 一个SecretKey对象 
	SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); 
	SecretKey securekey = keyFactory.generateSecret(dks); 
//	 Cipher对象实际完成解密操作 
	Cipher cipher = Cipher.getInstance(DES); 
//	 用密匙初始化Cipher对象 
	cipher.init(Cipher.DECRYPT_MODE, securekey, sr); 
//	 现在，获取数据并解密 
//	 正式执行解密操作 
	return cipher.doFinal(src); 
	}
	
	/**
	 * 文件加密
	 * @param oldFile 要加密文件绝对路径
	 * @param newFile 已加密文件存放路径
	 * @throws Exception
	 */
	public void encryptFile(String oldFile,String newFile) throws Exception{
		FileInputStream fis = new FileInputStream(oldFile);
		File f = new File(newFile);
		if(!f.exists())
			f.createNewFile();
		FileOutputStream fos = new FileOutputStream(f);
		byte[] buff = new byte[ENBUFFERLEN];
		fos.write(FILE_HEAD.getBytes());//添加文件头
		while(fis.read(buff)!=-1)
		{
			byte[] dsBuff = encrypt(buff,KEY.getBytes());
			fos.write(dsBuff);
		}
		fis.close();
		fos.close();
	}
	
	/**
	 * 文件解密
	 * @param oldFile 要解密文件绝对路径
	 * @param newFile 已解密文件存放路径
	 * @throws Exception
	 */
	public void decryptFile(String oldFile,String newFile) throws Exception{
		FileInputStream fis = new FileInputStream(oldFile);
		File f = new File(newFile);
		if(!f.exists())
			f.createNewFile();
		FileOutputStream fos = new FileOutputStream(f);
		byte[] buff = new byte[DEBUFFERLEN];
		fis.read(FILE_HEAD.getBytes());//去除文件头
		while(fis.read(buff)!=-1)
		{
			byte[] dsBuff = decrypt(buff,KEY.getBytes());
			fos.write(dsBuff);
		}
		fis.close();
		fos.close();
	}
	/**
	 * 判断文件是否加密
	 * @param file 文件路径
	 * @return true:加密文件；false:未加密文件
	 * @throws Exception
	 */
	public boolean isFileEncrypt(String file) throws Exception{
		FileInputStream fis = new FileInputStream(file);
		byte[] buff = new byte[FILE_HEAD.getBytes().length];
		fis.read(buff);
		fis.close();
		byte[] headBuff = FILE_HEAD.getBytes();
		if(buff.length==headBuff.length)
		{
			for(int i=0;i<buff.length;i++)
			{
				if(buff[i]!=headBuff[i])
				{
					return false;
				}
			}
			return true;
		}
		else
		{
			return false;
		}
	}
	/**
	 * 移动文件到指定目录下
	 * @param source 需要移动的文件
	 * @param targetPath 服务器根目录下的目标文件夹
	 * @param realPath 服务器物理路径
	 * @param targetFileName 目标文件名(若为null则与原文件同名)
	 */
	public static void moveFile(File source,String realPath,String targetPath,String targetFileName)
	{
		//目标文件
		File targetFile = new File(realPath+targetPath+(targetFileName==null?source.getName():targetFileName));
		//目标目录
		File path = new File(realPath+targetPath);
		//判断目录是否存在，不存在则创建目录
		if(!path.isDirectory())
		{
			path.mkdirs();
		}
		//若目标文件已存在则删除目标文件
		if(targetFile.exists()&&targetFile.isFile())
		{
			targetFile.delete();
		}
		source.renameTo(targetFile);
	}
}
